from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _

class ReversionedRevisioned(models.Model):
    """
    A class which offers some revision funcionalita based on the code
    from django-reversioned
    """
    revision_comment = models.TextField(_('comment'), blank=True)
    
    def revision_count(self):
        from reversion.models import Version
        version_list = Version.objects.get_for_object(self)
        return version_list.count()
    revision_count.short_description = _('revision')

    class Meta:
        abstract = True

class Revisioned(models.Model):
    track = None
    
    current_revision = models.PositiveIntegerField(blank=True, null=True, editable=False)
    last_modified_by = models.ForeignKey(User, blank=True, null=True, editable=False)
    last_modified_at = models.DateTimeField(auto_now=True)
    comment = models.TextField(blank=True)
    deleted = models.BooleanField(editable=False, default=False, help_text="Inserisci qui un eventuale commento per descrivere la modifica da te effettuata.")
    revisions = generic.GenericRelation('Revision')
    
    def save(self, action=None, **options):
        if self.track is None:
            raise ValueError('You have to define a field to track!')
            
        if self.action is None:
            if self.deleted:
                action = 2
            elif self.current_revision:
                action = 1
            else:
                action = 0
                
        if self.current_revision:
            self.current_revision = self.current_revision + 1
        else:
            self.current_revision = 1
        
        super(Revisioned, self).save(**options)
        
        r = Revision()
        r.user = self.last_modified_by
        r.revision = self.current_revision
        r.action = action
        r.content_object = self
        r.comment = self.comment
        r.content = getattr(self, self.track)
        r.save()
    
    def restore(self, commit=True):
        self.deleted = False
        
        if commit:
            self.save()
        
    def delete(self, **options):
        if self.deleted:
            super(Revisioned, self).delete(**options)
        else:
            self.deleted = True
            self.save()
        
    class Meta:
        abstract = True

class Revision(models.Model):
    ACTION_CHOICES = (
        (0, 'Inserted'),
        (1, 'Updated'),
        (2, 'Deleted'),
        (3, 'Restored')
    )
    
    content_type = models.ForeignKey(ContentType, blank=True, null=True)
    object_id = models.PositiveIntegerField(blank=True, null=True)
    content_object = generic.GenericForeignKey('content_type', 'object_id')
    
    revision = models.PositiveIntegerField(editable=False, blank=True)
    content = models.TextField(blank=True)
    comment = models.TextField(blank=True)
    user = models.ForeignKey(User, blank=True, null=True)
    date = models.DateTimeField(auto_now_add=True)
    action = models.PositiveSmallIntegerField(choices=ACTION_CHOICES)
